package com.xie.security.base;

import com.xie.common.constants.CodeEnum;
import com.xie.security.base.extension.UserContextAware;
import com.xie.security.exception.CustomAuthenticationException;
import com.xie.security.exception.ParseTokenException;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component

public class JwtAuthenticationProvider extends BaseAuthenticationProvider implements AuthenticationProvider {
  private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationProvider.class);

  //回调用户
  private final UserContextAware userContextAware;

  public JwtAuthenticationProvider(UserContextAware userContextAware) {
    this.userContextAware = userContextAware;
  }

  public Authentication authenticate(Authentication authentication) throws AuthenticationException {
    String token = (String)authentication.getCredentials();
    BaseJwtUser jwtUser = null;
    if (Objects.isNull(this.userContextAware)) {
      return authentication;
    } else {
      try {
        jwtUser = this.userContextAware.processToken(token);
      } catch (ParseTokenException var5) {
        throw new CustomAuthenticationException(var5.getCode(), var5.getMsg());
      } catch (Exception var6) {
        throw new CustomAuthenticationException(CodeEnum.SystemError.getCode(), CodeEnum.SystemError.getName());
      }

      UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(jwtUser, (Object)null, jwtUser.getAuthorities());
      SecurityContextHolder.getContext().setAuthentication(authToken);
      //放入上下文
      return authToken;
    }
  }

  public boolean supports(Class<?> authentication) {
    return JwtAuthToken.class.equals(authentication);
  }
}
